﻿using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Dynamic;
using System.Reflection;
using Castle.DynamicProxy;

namespace Crow.Library.Interceptors.DatabaseInceptors.DbOperations
{
    internal class DynamicArgumentHolder : DynamicObject // IDynamicMetaObjectProvider
    {
        private static readonly ConcurrentDictionary<string, ParameterInfo[]> ParametersList =
            new ConcurrentDictionary<string, ParameterInfo[]>();

        private readonly Dictionary<string, object> _values = new Dictionary<string, object>();


        public DynamicArgumentHolder(IInvocation invocation)
        {
            string key = string.Format("{0}:{1}", invocation.TargetType.Name, invocation.Method.Name);
            var parameters = ParametersList.GetOrAdd(key,
                                         invocation.InvocationTarget.GetType().GetInterfaces()[0].GetMethod(invocation.Method.Name).GetParameters());


            for (var i = 0; i < invocation.Arguments.Length; i++)
            {
                var v = invocation.Arguments[i];
                _values.Add(parameters[i].Name, v);
            }
        }

        public override bool TryGetIndex(GetIndexBinder binder, object[] indexes, out object result)
        {
            result = _values[indexes[0].ToString()];
            return true;
        }
    }
}